// the lock server implementation

#include "lock_server.h"
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>

lock_server::lock_server():
  nacquire (0),lock_map_mutex_(),lock_map_()
{
}

lock_protocol::status
lock_server::stat(int clt, lock_protocol::lockid_t lid, int &r)
{
  lock_protocol::status ret = lock_protocol::OK;
  printf("stat request from clt %d\n", clt);
  r = nacquire;
  return ret;
}

lock_protocol::status
lock_server::acquire(int clt, lock_protocol::lockid_t lid, int& r) {
  //printf("acquire request from clt %d lid=%016llx\n", clt, lid);
  std::shared_ptr<LocalLockStatus> local_lock;
  {
    std::lock_guard<std::mutex> lk(lock_map_mutex_);
    if (lock_map_.find(lid) == lock_map_.end()) {
      std::shared_ptr<LocalLockStatus> localLock =
          std::make_shared<LocalLockStatus>(clt);
      lock_map_[lid] = std::move(localLock);
    }
    local_lock = lock_map_[lid];
  }
  local_lock->Lock(clt);
  printf("xiaochao clt:%d acquired lid=%016llx\n", clt, lid);
  nacquire ++;
  return lock_protocol::OK;
}

lock_protocol::status
lock_server::release(int clt, lock_protocol::lockid_t lid, int& r) {
  //printf("release request from clt %d, lid = %016llx\n", clt, lid);
  std::shared_ptr<LocalLockStatus> local_lock;
  {
    std::lock_guard<std::mutex> lk(lock_map_mutex_);
    if (lock_map_.find(lid) == lock_map_.end()) {
      return lock_protocol::NOENT;
    }
    local_lock = lock_map_[lid];
  }
  if (local_lock->Release(clt)) {
    nacquire --;
    printf("xiaochao clt:%d release lid=%016llx\n", clt, lid);
    return lock_protocol::OK;
  } else {
    return lock_protocol::NOENT;
  }
}


